package com.fmy.mcsecurity.token.impl;

import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.StrUtil;
import com.fmy.mcsecurity.token.TokenStorage;
import com.fmy.mcsecurity.token.impl.jdbc.JdbcLoginService;
import com.fmy.mcsecurity.token.model.RefreshStorage;
import com.fmy.mcsecurity.token.model.SecurityToken;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.core.Authentication;
import org.springframework.transaction.annotation.Transactional;

import java.io.ByteArrayInputStream;
import java.util.Collections;
import java.util.List;

/**
 * @author Mr.fmy
 * @version 1.0.0
 * @ClassName JwtTokenGenerate
 * @Description TODO jdbc生成方式
 * @createTime 2019/12/9 11:06
 */
@Slf4j
public class JdbcTokenStorage implements TokenStorage {

    private final JdbcLoginService jdbcLoginService;
    private final int concurrency = 1;

    public JdbcTokenStorage(JdbcLoginService jdbcLoginService) {
        this.jdbcLoginService = jdbcLoginService;
    }

    @Override
    public String getUserKey(String token) {
        return jdbcLoginService.getByTokenToKey(token);
    }

    @Override
    public Authentication getAuthentication(String userKey) {
        byte[] bytes = jdbcLoginService.getByUserToInfo(userKey);
        if (bytes == null) {
            return null;
        }
        Object o = IoUtil.readObj(new ByteArrayInputStream(bytes));
        return (Authentication) o;
    }

    @Override
    public void updateAuthentication(String userKey, Authentication authentication) {
        jdbcLoginService.updateAuthentication(userKey, authentication);
    }

    @Override
    public void setAuthentication(String client, String type, String userKey, Authentication authentication, SecurityToken token) {
        jdbcLoginService.save(client, type, userKey, authentication, token);
    }

    @Override
    public List<SecurityToken> getToken(String userKey) {
        return Collections.singletonList(jdbcLoginService.getUserKeyToSecurityStorage(userKey));
    }

    @Override
    public RefreshStorage getRefreshTokenStorage(String refreshtoken) {
        return jdbcLoginService.getRefreshTokenToStorage(refreshtoken);
    }

    @Override
    public void kick(String token, String cause) {
        String userKey = getUserKey(token);
        kickUserKey(userKey, cause);
    }

    @Override
    public String getkickCause(String token) {
        return "";
    }

    @Override
    @Transactional(rollbackFor = {Exception.class})
    public void setAuthenticationConcurrency(String client, String type, String userKey, Authentication authentication, SecurityToken token) {
        kickUserKey(userKey, "您的账号在别处登录，如不是本人操作，请及时修改密码");
        setAuthentication(client, type, userKey, authentication, token);
    }

    @Override
    public int concurrency() {
        return concurrency;
    }

    @Override
    public void kickUserKey(String userKey, String cause) {
        if (StrUtil.isNotBlank(userKey)) {
            jdbcLoginService.del(userKey);
        }
    }
}
